﻿using Mapster;
using Raffles.OA.Data;
using Raffles.OA.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Raffles.OA.WebApp.Areas.Manage.Controllers
{
    public class UserController : BaseController<User>
    {
        /// <summary>
        /// 获取用户分页列表
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public ActionResult GetPageListJson(UserSearchParam param, Pagination pagination)
        { 
            var users = _dbContext.Queryable<User>().Includes(x => x.Roles)
                                                    .Includes(x => x.Department)
                                                    .Where(x => !x.DeletedMark && !x.IsSystem && x.Id != OperatorProvider.Provider.GetCurrent().Id)
                                                    .WhereIF(!param.KeyWord.IsEmpty(), x => x.Account == param.KeyWord.Trim() || x.RealName == param.KeyWord.Trim())
                                                    .WhereIF(param.EnabledMark.HasValue, x => x.EnabledMark == param.EnabledMark.ToBool())
                                                    .ToList();
            var departs = _dbContext.Queryable<Department>().ToChildList(x => x.ParentId, param.DepartmentId);
            users = users.Where(x => departs.Any(y => y.Id == x.DepartmentId)).ToList();
            int totalCount = users.Count;
            users = users.Skip(pagination.PageSize * (pagination.PageIndex - 1)).Take(pagination.PageSize).ToList();
            return Content(DataResult<List<User>>.PageResult(users, totalCount).ToJson());
        }

        public ActionResult Form(int? id)
        {
            User user = new User();
            var roles = _dbContext.Queryable<Role>()
                                      .Where(x => !x.DeletedMark && x.EnabledMark)
                                      .Select(x => new { x.Id, x.Name, x.DisplayOrder })
                                      .OrderBy(x => x.DisplayOrder)
                                      .ToList();
            if (id != null)
            {
                user = _dbContext.Queryable<User>().InSingle(id);
                var roleId = (_dbContext.Queryable<UserRole>().First(x => x.UserId == id)?.RoleId) ?? 0;
                ViewBag.RoleId = new SelectList(roles, "Id", "Name", roleId);
            }
            else
            {
                ViewBag.RoleId = new SelectList(roles, "Id", "Name", 0);
            }
            return View(user);
        }

        /// <summary>
        /// 用户保存
        /// </summary>
        /// <param name="userDto"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SaveForm(UserDto userDto)
        {
            try
            {
                _dbContext.Ado.BeginTran();
                if (userDto.Id == null)
                {
                    if (_dbContext.Queryable<User>().Any(x => !x.DeletedMark && x.Account.Equals(userDto.Account)))
                    {
                        return Json(DataResult.Error("用户账号不允许重复"));
                    }
                    //用户信息
                    var salt = Md5Helper.md5(CommonHelper.CreateRandomCode(8)).ToLower();
                    User user = new User();
                    userDto.Adapt(user);
                    user.Salt = salt;
                    user.Password = CommonHelper.CreatePassword("123456", salt);
                    user.DepartmentId = userDto.TreeId;
                    user.PositionId = userDto.PositionIds.ParseToStrings<int>();
                    user.CreatedOn = DateTime.Now;
                    user.CreatedBy = OperatorProvider.Provider.GetCurrent().Id;
                    int retId = _dbContext.Insertable<User>(user).ExecuteReturnIdentity();

                    //用户角色信息
                    UserRole userRole = new UserRole();
                    userRole.UserId = retId;
                    userRole.RoleId = userDto.RoleId;
                    _dbContext.Insertable<UserRole>(userRole).ExecuteCommand();
                }
                else
                {
                    if (_dbContext.Queryable<User>().Any(x => !x.DeletedMark && x.Account.Equals(userDto.Account) && x.Id != userDto.Id))
                    {
                        return Json(DataResult.Error("用户账号不允许重复"));
                    }
                    //用户信息
                    User user = _dbContext.Queryable<User>().InSingle(userDto.Id);
                    userDto.Password = user.Password;
                    userDto.Adapt(user);
                    user.DepartmentId = userDto.TreeId;
                    user.PositionId = userDto.PositionIds.ParseToStrings<int>();
                    user.UpdatedOn = DateTime.Now;
                    user.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                    _dbContext.Updateable<User>(user).ExecuteCommand();

                    //删除当前角色
                    _dbContext.Deleteable<UserRole>().Where(x => x.UserId == userDto.Id).ExecuteCommand();
                    //用户角色信息
                    UserRole userRole = new UserRole();
                    userRole.UserId = user.Id;
                    userRole.RoleId = userDto.RoleId;
                    _dbContext.Insertable<UserRole>(userRole).ExecuteCommand();
                }
                _dbContext.Ado.CommitTran();
                return userDto.Id == null ? Json(DataResult.Success($"新增成功")) : Json(DataResult.Success($"修改成功"));
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                return Json(DataResult.Error($"保存失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 状态改变
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult ChangeStatus(int id)
        {
            User user = _dbContext.Queryable<User>().InSingle(id);
            var result = user.EnabledMark;
            user.EnabledMark = !user.EnabledMark;
            user.UpdatedOn = DateTime.Now;
            user.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
            _dbContext.Updateable<User>(user).ExecuteCommand();
            return result == true ? Json(DataResult.Success("禁用成功")) : Json(DataResult.Success("启用成功"));
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult DeleteData(int id)
        {
            //删除用户时  同步需要删除角色用户里关联的用户信息
            try
            {
                _dbContext.Ado.BeginTran();
                //删除角色里的该用户
                var userRoles = _dbContext.Queryable<UserRole>().Where(x => x.UserId == id).ToList();
                _dbContext.Deleteable<UserRole>(userRoles).ExecuteCommand();

                //删除用户
                User user = _dbContext.Queryable<User>().InSingle(id);
                user.DeletedMark = true;
                user.UpdatedOn = DateTime.Now;
                user.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                _dbContext.Updateable<User>(user).ExecuteCommand();

                _dbContext.Ado.CommitTran();
                return Json(DataResult.Success("删除成功"));
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                return Json(DataResult.Error($"删除失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult ResetPwd(int id)
        {
            User user = _dbContext.Queryable<User>().InSingle(id);
            user.Password = CommonHelper.CreatePassword("123456", user.Salt);
            user.UpdatedOn = DateTime.Now;
            user.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
            _dbContext.Updateable<User>(user).ExecuteCommand();
            return Json(DataResult.Success($"密码重置成功"));
        }

        /// <summary>
        /// 获取用户的按钮权限信息(这里取用户按钮权限和角色按钮权限并集)
        /// </summary>
        /// <returns></returns>
        public ActionResult GetUserAuthorizeJson()
        {
            UserAuthorizeVo userAuthorizeVo = new UserAuthorizeVo();
            var user = _dbContext.Queryable<User>()
                                 .Includes(x => x.Roles, x => x.Menus)
                                 .Includes(x => x.Menus)
                                 .First(x => x.Id == OperatorProvider.Provider.GetCurrent().Id);
            userAuthorizeVo.IsSystem = OperatorProvider.Provider.GetCurrent().IsSystem;
            if (!user.IsSystem)
            {
                List<ButtonAuthorize> roleButtons = user.Roles.FirstOrDefault()?.Menus
                                                            .Where(x => x.Type == (int)MenuTypeEnum.Button)
                                                            .Select(x => new ButtonAuthorize
                                                            {
                                                                MenuButtonId = x.Id,
                                                                Authorize = x.Authorize
                                                            }).ToList();
                List<ButtonAuthorize> userButtons = user.Menus
                                                            .Where(x => x.Type == (int)MenuTypeEnum.Button)
                                                            .Select(x => new ButtonAuthorize
                                                            {
                                                                MenuButtonId = x.Id,
                                                                Authorize = x.Authorize
                                                            }).ToList();
                List<ButtonAuthorize> buttons = roleButtons.Concat(userButtons).GroupBy(x => new { x.MenuButtonId, x.Authorize }).Select(x => x.First()).ToList();
                userAuthorizeVo.ButtonAuthorizes = buttons;
            }
            return Json(DataResult<UserAuthorizeVo>.Success(userAuthorizeVo, "加载成功"), JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 文件导出
        /// </summary>
        [HttpPost]
        public ActionResult ExportUserJson(UserSearchParam param)
        {
            var users = _dbContext.Queryable<User>().Includes(x => x.Roles)
                                                   .Includes(x => x.Department)
                                                   .Where(x => !x.DeletedMark && !x.IsSystem && x.Id != OperatorProvider.Provider.GetCurrent().Id)
                                                   .WhereIF(!param.KeyWord.IsEmpty(), x => x.Account == param.KeyWord.Trim() || x.RealName == param.KeyWord.Trim())
                                                   .WhereIF(param.EnabledMark.HasValue, x => x.EnabledMark == param.EnabledMark.ToBool())
                                                   .ToList();
            if (users.Count() == 0)
            {
                return Content(DataResult<int>.Warn(0, "暂无数据导出").ToJson());
            }
            //导出列名
            string[] column = new string[] { "DepartmentName", "Account", "RealName", "MobilePhone" };
            //文件名
            var fileName = "用户信息.xls";
            //表头
            var headerText = "用户信息";
            var file = ExcelHelper<User>.ExportToExcel(fileName, headerText, users, column);
            return Content(DataResult<string>.Success(file, "导出成功").ToJson());
        }

        /// <summary>
        /// 获取审批用户列表
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public ActionResult GetAuditListJson(BaseSearchParam param)
        {
            var users = _dbContext.Queryable<User>().Includes(x => x.Department).Includes(x => x.Roles)
                                                    .Where(x => !x.DeletedMark && !x.IsSystem)
                                                    .WhereIF(!param.KeyWord.IsEmpty(), x => x.Account == param.KeyWord.Trim() || x.RealName == param.KeyWord.Trim())
                                                    .ToList();
            return Content(DataResult<List<User>>.Success(users).ToJson());
        }

        /// <summary>
        /// 用户授权
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public ActionResult Authorize(int userId)
        {
            var userMenus = _dbContext.Queryable<User>().Includes(x => x.Menus).First(x => x.Id == userId);
            return View(userMenus);
        }

        /// <summary>
        /// 保存用户权限
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="menuIds"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SaveMenus(int userId, string menuIds)
        {
            try
            {
                _dbContext.Ado.BeginTran();
                var roleMenusOld = _dbContext.Queryable<RoleMenu>().Where(x => x.UserId == userId).ToList();
                _dbContext.Deleteable<RoleMenu>(roleMenusOld).ExecuteCommand();
                //保存现有权限
                List<int> menus = Array.ConvertAll<string, int>(menuIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => s.StringToInt32()).Distinct().ToList();
                List<RoleMenu> roleMenusNew = new List<RoleMenu>();
                foreach (var menuId in menus)
                {
                    roleMenusNew.Add(new RoleMenu() { UserId = userId, MenuId = menuId });
                }
                _dbContext.Insertable<RoleMenu>(roleMenusNew).ExecuteCommand();
                _dbContext.Ado.CommitTran();
                return Json(DataResult.Success("权限分配成功"));
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                return Json(DataResult.Error($"保存失败,失败原因:{ex.Message}"));
            }
        }
    }
}